home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Other Stuff / Demos ƒ / TOPS SoftTalk Package / STClient ƒ / STClient.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-08  |  13.3 KB  |  427 lines  |  [TEXT/MPS ]

  1. /*
  2. ------------------------------------------------------------------------------
  3. |    Sun Microsystems, TOPS Division
  4. |    950 Marina Village Parkway
  5. |    P.O. Box 4016
  6. |    Alameda, CA 94501
  7. |    
  8. |    Copyright (c) 1989 Sun Microsystems, Inc. All rights reserved.
  9. |    
  10. |    Sun considers its source code as an unpublished, proprietary trade secret,
  11. |    and it is available only under strict license provisions. This copyright
  12. |    notice is placed here only to protect Sun in the event the source is deemed
  13. |    a published work. Disassembly, decompilation, or other means of reducing the
  14. |    object code to human readable form is prohibited by the license agreement
  15. |    under which this code is provided to the user or company in possession of
  16. |    this copy.
  17. |    
  18. |    RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the Government
  19. |    is subject to restrictions as set forth in subparagraph (c) (1) (ii) of the
  20. |    Rights in Technical Data and Computer Software clause at DFARS 52.227-7013
  21. |    and in similar clauses in the FAR and NASA FAR supplement.
  22. ------------------------------------------------------------------------------
  23. */
  24.  
  25.  
  26.  
  27. /*
  28. ================================================================================
  29. **
  30. **    Project:    SoftTalk
  31. **
  32. **    File:        STClient.c
  33. **
  34. **    Purpose:
  35. **        This file implements the sample SoftTalk client.  It demonstrates how to
  36. **        look up a server, how to connect to a server, and how to make RPC calls
  37. **        to the server.
  38. **
  39. **    ----------------------------------------------------------------------------
  40. **
  41. **    Version        Date        Author        Description
  42. **    -------        ----        ------        -----------
  43. **    1.0.1        17-Aug-89     MAC            First draft.
  44. **
  45. ================================================================================
  46. */
  47.  
  48.  
  49.  
  50. /*
  51. **    ----------------------------------------------------------------------------
  52. **        INCLUDES
  53. **    ----------------------------------------------------------------------------
  54. */
  55. #include "STClient.h"
  56. #include <MacTypes.h>
  57.  
  58.  
  59.  
  60. /*
  61. **    ----------------------------------------------------------------------------
  62. **        CONST
  63. **    ----------------------------------------------------------------------------
  64. */
  65.  
  66. #define kListLoopCount (5)
  67.     /* how many times to loop calling STList() */
  68.  
  69. #define kNoClient (0)
  70.     /* we don't have a client yet */
  71.  
  72.  
  73. /*
  74. **    ----------------------------------------------------------------------------
  75. **        VAR
  76. **    ----------------------------------------------------------------------------
  77. */
  78. STSession gClientID = kNoClient;
  79.     /* the SoftTalk magic cookie for our client.  Initialized to kNoClient so it
  80.         represents an invalid value.  Only after calling STCreateClient() will
  81.         this value be valid */
  82.  
  83.  
  84. /*
  85. **    ----------------------------------------------------------------------------
  86. **        PROTOTYPES
  87. **    ----------------------------------------------------------------------------
  88. */
  89. static INT32 _MyNotify(void);
  90. static INT32 MyNotify(STSession session, INT32 why, Func32Ptr f, INT32 arg);
  91.  
  92.  
  93.  
  94. /*
  95. **    ----------------------------------------------------------------------------
  96. **    FUNCTION MyNotify() => INT32 : do we abort the session?
  97. **    ----------------------------------------------------------------------------
  98. **
  99. **    Purpose:
  100. **        This interrupt-level routine is called from SoftTalk when there are problems
  101. **        reaching the server.  We decide whether to abort the session, and can take
  102. **        appropriate action to clean-up our state.  This sample always aborts and
  103. **        takes no clean-up actions.
  104. **
  105. **    Usage:
  106. **        When we create a session we tell SoftTalk to use this as the Notify function
  107. **        for the session.  Since SoftTalk passes args in registers, we have some asm
  108. **        glue that pushes the args onto the stack and then executes a standard C function
  109. **        call.
  110. **        This asm glue routine is registered with SoftTalk, and will then be called by
  111. **        SoftTalk (at interrupt time) whenever the session is in trouble.
  112. **
  113. **    ----------------------------------------------------------------------------
  114. **    Version        Date        Author        Description
  115. **    -------        ----        ------        -----------
  116. **    01a             8/17/89     MAC            First draft.
  117. **    ----------------------------------------------------------------------------
  118. */
  119.  
  120. static INT32 _MyNotify(void) {
  121.     asm    {
  122.         move.l    d3,-(sp)        /* move "INT32 arg" onto the stack */
  123.         move.l    d2,-(sp)        /* move "Func32Ptr F" onto the stack */
  124.         move.l    d1,-(sp)        /* move "INT32 why" onto the stack */
  125.         move.l    d0,-(sp)        /* move "STSession session" onto the stack */
  126.         jsr        MyNotify            /* call the C routine */
  127.         add.l    #16,sp                /* clean up the stack */
  128.         }
  129. }
  130.  
  131. static INT32 MyNotify(STSession session, INT32 why, Func32Ptr F, INT32 arg) {
  132.     return((INT32)TRUE);
  133. }
  134.  
  135.  
  136.  
  137.  
  138.  
  139. /*
  140. **    ----------------------------------------------------------------------------
  141. **    FUNCTION STClientCreate() => INT32 : initialize the sample Client
  142. **    ----------------------------------------------------------------------------
  143. **
  144. **    Purpose:
  145. **        Initialize the client by: initialize SoftTalk using STInitialize();
  146. **        find all servers that match our server's description using STList();
  147. **        open a session to our server using STOpenSession() (I cheat since I know the
  148. **        exact name of my server); clean-up by calling STUnlist().
  149. **
  150. **    Usage:
  151. **        after creating a client object with the new operator, immediately call
  152. **        this method in order to initialize the client.
  153. **
  154. **    ----------------------------------------------------------------------------
  155. **    Version        Date        Author        Description
  156. **    -------        ----        ------        -----------
  157. **    01a             8/17/89     MAC            First draft.
  158. **    ----------------------------------------------------------------------------
  159. */
  160.  
  161. INT32 STClientCreate(void) {
  162.  
  163.     short         i;                        /* loop counter */
  164.     STSession    myClient;            /* the session "magic cookie" returned by SoftTalk */
  165.     STResult    err;                    /* result code */
  166.     STServerSpecPtr pElt;        /* ptr to a Server Spec that will be created by STLIst */ 
  167.     BYTE*            searchSpec;        /* NBP spec for servers I want to match */
  168.     BYTE*            nameSpec;            /* actual NBP spec for my server */
  169.     
  170.     
  171.         /* do we have a client already?  If yes then simply return */
  172.     if (gClientID != kNoClient) {
  173.         return(noErr);
  174.         }
  175.     
  176.     
  177.         /* initialize the NBP spec to find the appropriate servers.  My server is
  178.             of type "Dude", so I look for "=:Dude@*" which means "find all servers of
  179.             type Dude in the current zone.  For more info, see the description of
  180.             NBP names in Inside Mac */
  181.     searchSpec = (BYTE*)"\p=:Dude@*";
  182.     nameSpec = (BYTE*)"\pMichael:Dude@*";
  183.  
  184.  
  185.         /* initialize SoftTalk */
  186.     err = STInitialize();
  187.     if (err != noErr) {
  188.         return(err);
  189.         }
  190.         
  191.     
  192.         /* SoftTalk has been initialized.  We now
  193.             list all servers that match what I'm looking for.
  194.             If STList starts an async lookup, it will return kStillLooking; I need to then
  195.             call STList again to actually get some values */
  196.     err = STList(&pElt, searchSpec);
  197.  
  198.     if (err == kStillLooking) {    /* started async lookup so call it again a couple of times */
  199.         for(i = 0; (i < kListLoopCount) && ( (err == noErr) || (err == kStillLooking) ); i++) {
  200.             err = STList(&pElt, searchSpec);
  201.             }
  202.         }
  203.     
  204.     
  205.     /* check errors for STList */
  206.     if (err < noErr) {
  207.         return(err); /* SoftTalk error */
  208.         }
  209.     else if (err == 0) {
  210.         return(kENoServerFound); /* no servers matched my spec */
  211.         }
  212.  
  213.  
  214.     /* we found some servers!  Let's open a session to one of them.
  215.         I already know the name of the sample server, so instead of
  216.         extracting the name from the list returned by STList, I call STOpenSession
  217.         with my predefined name.  You should really extract the names and choose one
  218.         of them */
  219.     err = STOpenSession(&myClient, nameSpec, _MyNotify, kDefaultRequests);
  220.     gClientID = myClient;
  221.         
  222.     if (err > noErr) {
  223.         /* deallocate the list created by SoftTalk */
  224.         err = STUnlist(searchSpec);
  225.         }
  226.     else if (err == 0) {
  227.         /* no servers found */
  228.         err = kENoServerFound;
  229.         }
  230.  
  231.     return(err);
  232. }
  233.  
  234.  
  235.  
  236. /*
  237. **    ----------------------------------------------------------------------------
  238. **    FUNCTION STClientDispose() => STResult : dispose of the client
  239. **    ----------------------------------------------------------------------------
  240. **
  241. **    Purpose:
  242. **        clean-up the client when you're done with it by closing the session
  243. **        using STCloseSession().
  244. **
  245. **    Usage:
  246. **        call this when you're done with the SoftTalk client.
  247. **
  248. **    ----------------------------------------------------------------------------
  249. **    Version        Date        Author        Description
  250. **    -------        ----        ------        -----------
  251. **    01a             8/17/89     MAC            First draft.
  252. **    ----------------------------------------------------------------------------
  253. */
  254.  
  255. STResult STClientDispose(void){
  256.     STResult result;
  257.     
  258.     if (gClientID != kNoClient) {
  259.         result = STCloseSession(gClientID);
  260.         gClientID = kNoClient;
  261.         }
  262.     else {
  263.         result = noErr;
  264.         }
  265.     return(result);
  266. }
  267.  
  268.  
  269.  
  270.  
  271.  
  272. /*
  273. **    ----------------------------------------------------------------------------
  274. **    FUNCTION Func1() => INT32 : sample stub routine
  275. **    ----------------------------------------------------------------------------
  276. **
  277. **    Purpose:
  278. **        This is a sample stub for an RPC call to the server with no args.
  279. **
  280. **    Usage:
  281. **        call this function when you want to invoke an RPC call.
  282. **
  283. **    ----------------------------------------------------------------------------
  284. **    Version        Date        Author        Description
  285. **    -------        ----        ------        -----------
  286. **    01a             8/17/89     MAC            First draft.
  287. **    ----------------------------------------------------------------------------
  288. */
  289.  
  290. INT32 Func1(void){
  291.     STResult err;
  292.     INT32 result = (-1);            /* initialize return value to failure */
  293.     BYTE* format = (BYTE*)"";    /* the string specifying the format of the arguments */
  294.     
  295.     err = STAsk(gClientID, &result, (UINT32)'F1', format);
  296.     return(result);
  297. }
  298.  
  299.  
  300.  
  301.  
  302.  
  303. /*
  304. **    ----------------------------------------------------------------------------
  305. **    FUNCTION Func2() => INT32 : sample stub routine
  306. **    ----------------------------------------------------------------------------
  307. **
  308. **    Purpose:
  309. **        This is a sample stub for an RPC call to the server with one INT32 arg.
  310. **
  311. **    Usage:
  312. **        call this function when you want to invoke an RPC call.
  313. **
  314. **    ----------------------------------------------------------------------------
  315. **    Version        Date        Author        Description
  316. **    -------        ----        ------        -----------
  317. **    01a             8/17/89     MAC            First draft.
  318. **    ----------------------------------------------------------------------------
  319. */
  320.  
  321. INT32 Func2(INT32 arg1){
  322.     STResult err;
  323.     INT32 result = (-1);                /* initialize return value to failure */
  324.     BYTE* format = (BYTE*)"4";    /* the string specifying the format of the arguments */
  325.     
  326.     err = STAsk(gClientID, &result, (UINT32)'F2', format, (STArg) arg1);
  327.                                         /* cast each argument to an STArg!!!     ^            */
  328.     return(result);
  329. }
  330.  
  331.  
  332.  
  333.  
  334.  
  335. /*
  336. **    ----------------------------------------------------------------------------
  337. **    FUNCTION Func3() => INT32 : sample stub routine
  338. **    ----------------------------------------------------------------------------
  339. **
  340. **    Purpose:
  341. **        This is a sample stub for an RPC call to the server with two args.
  342. **
  343. **    Usage:
  344. **        call this function when you want to invoke an RPC call.
  345. **
  346. **    ----------------------------------------------------------------------------
  347. **    Version        Date        Author        Description
  348. **    -------        ----        ------        -----------
  349. **    01a             8/17/89     MAC            First draft.
  350. **    ----------------------------------------------------------------------------
  351. */
  352.  
  353. INT32 Func3(INT32 arg1, INT16 arg2){
  354.     STResult err;
  355.     INT32 result = (-1);                /* initialize return value to failure */
  356.     BYTE* format = (BYTE*)"42";    /* the string specifying the format of the arguments */
  357.     
  358.     err = STAsk(gClientID, &result, (UINT32)'F3', format, (STArg) arg1, (STArg) arg2);
  359.                                         /* cast each argument to an STArg!!!     ^                                ^        */
  360.     return(result);
  361. }
  362.  
  363.  
  364.  
  365.  
  366.  
  367. /*
  368. **    ----------------------------------------------------------------------------
  369. **    FUNCTION Func4() => INT32 : sample stub routine
  370. **    ----------------------------------------------------------------------------
  371. **
  372. **    Purpose:
  373. **        This is a sample stub for an RPC call to the server with one C-string arg.
  374. **
  375. **    Usage:
  376. **        call this function when you want to invoke an RPC call.
  377. **
  378. **    ----------------------------------------------------------------------------
  379. **    Version        Date        Author        Description
  380. **    -------        ----        ------        -----------
  381. **    01a             8/17/89     MAC            First draft.
  382. **    ----------------------------------------------------------------------------
  383. */
  384.  
  385. INT32 Func4(char* arg1){
  386.     STResult err;
  387.     INT32 result = (-1);                /* initialize return value to failure */
  388.     BYTE* format = (BYTE*)"C";    /* the string specifying the format of the arguments */
  389.     
  390.     err = STAsk(gClientID, &result, (UINT32)'F4', format, (STArg) arg1);
  391.                                         /* cast each argument to an STArg!!!     ^            */
  392.     return(result);
  393. }
  394.  
  395.  
  396.  
  397.  
  398.  
  399. /*
  400. **    ----------------------------------------------------------------------------
  401. **    FUNCTION Func5() => INT32 : sample stub routine
  402. **    ----------------------------------------------------------------------------
  403. **
  404. **    Purpose:
  405. **        This is a sample stub for an RPC call to the server with one P-string arg.
  406. **
  407. **    Usage:
  408. **        call this function when you want to invoke an RPC call.
  409. **
  410. **    ----------------------------------------------------------------------------
  411. **    Version        Date        Author        Description
  412. **    -------        ----        ------        -----------
  413. **    01a             8/17/89     MAC            First draft.
  414. **    ----------------------------------------------------------------------------
  415. */
  416.  
  417. INT32 Func5(Str255 pString){
  418.     STResult err;
  419.     INT32 result = (-1);                /* initialize return value to failure */
  420.     BYTE* format = (BYTE*)"P";    /* the string specifying the format of the arguments */
  421.     
  422.     err = STAsk(gClientID, &result, (UINT32)'F5', format, (STArg) pString);
  423.                                         /* cast each argument to an STArg!!!     ^            */
  424.     return(result);
  425. }
  426.     
  427.